package com.piece.mall.service;

import com.piece.core.framework.enums.StatusType;
import com.piece.core.framework.enums.sql.SqlKey;
import com.piece.core.framework.support.bootstrap.Order;
import com.piece.core.framework.support.bootstrap.TreeData;
import com.piece.core.framework.util.object.ObjectUtil;
import com.piece.core.jpa.repository.BaseService;
import com.piece.mall.model.PmsCategory;
import com.piece.mall.repository.PmsCategoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Transactional
public class PmsCategoryService extends BaseService<PmsCategory, String> {

    @Autowired
    private PmsCategoryRepository pmsCategoryRepository;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @PostConstruct
    public void initRepository() {
        setRepository(pmsCategoryRepository);
    }

    @Override
    public List<PmsCategory> findAll() {
        return pmsCategoryRepository.findByCondition("showStatus", StatusType.NORMAL.getCode(), generateDefaultOrder());
    }

    public List<PmsCategory> findByParent(Long parentCid) {
        HashMap<String, Object> condition = new HashMap<>();
        condition.put("parentCid", parentCid);
        condition.put("showStatus", StatusType.NORMAL.getCode());
        return pmsCategoryRepository.findByCondition(condition, generateDefaultOrder());
    }

    /**
     * 获取下一个序号
     *
     * @param category
     */
    public Long findNextCategorySort(PmsCategory category) {
        String sql = "select ifnull(max(category_sort) + 1,1) from pms_category where parent_cid = " + category.getParentCid();
        return jdbcTemplate.queryForObject(sql, Long.class);
    }

    /**
     * 查询分类名称
     *
     * @param catId
     */
    public String findNameById(Long catId) {
        List<String> result = jdbcTemplate.queryForList("select name from pms_category where cat_id = ?", String.class, new Object[]{ catId });
        if (ObjectUtil.isNotEmpty(result)) {
            return result.get(0);
        }
        return null;
    }

    /**
     * 查询分类完整路径
     *
     * @param catId
     */
    public String[] findPathById(Long catId) {
        List<String> path = new ArrayList<>();
        List<String> fullPath = findParentPath(catId, path);
        Collections.reverse(fullPath);
        return fullPath.toArray(new String[fullPath.size()]);
    }

    private List<String> findParentPath(Long catId, List<String> path) {
        path.add(catId + "");
        PmsCategory category = this.findById(catId);
        if (0 != category.getParentCid()) {
            findParentPath(category.getParentCid(), path);
        }
        return path;
    }

    /**
     * 查询分类完整路径名称
     *
     * @param catId
     */
    public String[] findPathNameById(Long catId) {
        List<String> path = new ArrayList<>();
        PmsCategory category = this.findById(catId);
        List<String> fullPath = findParentPathName(catId, category.getName(), path);
        Collections.reverse(fullPath);
        return fullPath.toArray(new String[fullPath.size()]);
    }

    private List<String> findParentPathName(Long catId, String name, List<String> path) {
        path.add(name + "");
        PmsCategory category = this.findById(catId);
        if (0 != category.getParentCid()) {
            findParentPathName(category.getParentCid(), category.getName(), path);
        }
        return path;
    }

    /**
     * 对象转分类树
     *
     * @param categoryList 分类列表
     * @return
     */
    public List<TreeData> findTreeData(List<PmsCategory> categoryList) {
        return findTreeData(categoryList, false, null);
    }

    /**
     * 对象转分类树
     *
     * @param categoryList 分类列表
     * @param isCheck      是否需要选中
     * @param selectedList 已存在分类列表
     * @return
     */
    public List<TreeData> findTreeData(List<PmsCategory> categoryList, boolean isCheck, List<String> selectedList) {
        List<TreeData> trees = new ArrayList<>();
        boolean checked;
        for (PmsCategory category : categoryList) {
            TreeData treeData = TreeData.builder()
                    .id(String.valueOf(category.getCatId()))
                    .pId(String.valueOf(category.getParentCid()))
                    .title(category.getName())
                    .name(category.getName())
                    .build();

            if (isCheck) {
                checked = selectedList.contains(category.getCatId().toString());
                treeData.setChecked(checked);
            } else {
                treeData.setChecked(false);
            }
            trees.add(treeData);
        }
        return trees;
    }

    @Override
    protected List<Order> generateDefaultOrder() {
        return Stream.of(new Order("parentCid", SqlKey.ASC), new Order("categorySort", SqlKey.ASC)).collect(Collectors.toList());
    }
}
